package beans;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import model.Folder;
import model.Repository;
import model.Resource;
import conversions.Conversions;
import customExceptions.UserLostRightsException;
import dao.FolderDao;
import dao.HistoryDao;
import dao.ResourceDao;
import dao.ServerLogEntryDao;
import dao.UserDao;
import dto.ResourceDTO;
import enumerations.LogType;
import enumerations.Type;
import enumerations.UserType;


/**
 * @author Zsombor
 */
@Stateless

public class ResourcesBean implements ResourcesBeanRemote {
	
	@EJB
	Conversions conv;
	
	@EJB
	FolderDao folderDao;
	@EJB
	UserDao userDao;
	@EJB
	ResourceDao resourceDao;
	@EJB
	HistoryDao historyDao;


	@EJB
	ServerLogEntryDao serverLogDao;
	
	/**
     * Description: Delete resource
     * @author Zsombor+tokea+zahariem
     * @param reDto RsourceDTO
     */
	@Override
	public void deleteResource(int resourceId, int authorId) {
		Resource r = resourceDao.getResourceById(resourceId);
		Folder repository =  r.getRepository();
		
		
		if (userDao.isSupervisor(authorId, repository.getId()) || userDao.getUserById(authorId).getUserType()==UserType.admin){
			resourceDao.deleteResource(resourceId);
		}
		
		historyDao.removeHistory(resourceId);
		Date date = new Date();
		String content = "Resource deleted by supervisor "+authorId+" "+userDao.getUserById(authorId).getName();
		serverLogDao.insertOpToLog(LogType.unlock_resource, content, date, userDao.getUserById(authorId));
	}

	/**
	 * Description: Unlock resource so that it can be used by others
	 * 
	 * @author Zsombor
	 * @param reDto
	 *            RsourceDTO
	 */
	@Override
	public void unlockResource(int resourceId, int authorId) {
		
		Resource r = resourceDao.getResourceById(resourceId);
		Repository repository = (Repository) r.getRepository();
		
		
		if (userDao.isSupervisor(authorId, repository.getId()) || userDao.getUserById(authorId).getUserType()==UserType.admin){
			resourceDao.unlockResource(resourceId);
		}
		
		
		Date date = new Date();
		String content = "Resource unlocked by supervisor "+authorId+" "+userDao.getUserById(authorId).getName();
		serverLogDao.insertOpToLog(LogType.unlock_resource, content, date, userDao.getUserById(authorId));
	}
	
	/**
	 * Description: Create new resource
	 * 
	 * @author Zsombor+tokea+zahariem
	 * @param reDto
	 *            RsourceDTO
	 */
	@Override
	public ResourceDTO createResource(ResourceDTO reDto,int authorId) {
		int idParent = reDto.getFolderId();
		Resource newResource = new Resource();
		newResource.setContent(reDto.getContent());
		newResource.setFolder(folderDao.getFolderByID(idParent));
		newResource.setLockUser(userDao.getUserById(1));
		newResource.setName(reDto.getName());
		int newVersion = folderDao.getNewVersion(idParent);
		newResource.setVersion(newVersion);
		resourceDao.persistResource(newResource);
		reDto.setVersion(newVersion);
		reDto.setId(newResource.getId());
		reDto.setLockerId(1);
		folderDao.setParentFoldersVersion(newVersion, idParent);
		
		Date date = new Date();
		String contentH = "Resource created by "+authorId+" "+userDao.getUserById(authorId).getName();
		historyDao.addChangeToHistory(authorId, newResource.getId(), Type.create_resource, contentH, date);
		String content = "Resource created by "+authorId+" "+userDao.getUserById(authorId).getName();
		serverLogDao.insertOpToLog(LogType.create_resource, content, date, userDao.getUserById(authorId));
		
		resourceDao.unlockResource(reDto.getId());
		return reDto;
	}
	
	/**
	 * @author fodorl
	 * @return List<ResourceDTO>
	 * returneaza toata lista de resurse din baza de date ca lista de ResourceDTO
	 */

	@Override
	public List<ResourceDTO> getAllResources() {
		List<Resource> resources = new ArrayList<Resource>();
		resources = resourceDao.getAllResources();
		List<ResourceDTO> resourcesDTO = new ArrayList<ResourceDTO>();
		for (Resource resource : resources) {
			resourcesDTO.add(conv.resourceToDTO(resource));
		}
		return resourcesDTO;
	}
	
	/**
	 * @author fodorl
	 * @return List<ResourceDTO>
	 * @param idRepository
	 * returneza o lista de ResourceDTO care se afla in repository-ul cu id-ul dat
	 */

	@Override
	public List<ResourceDTO> getResourcesFromRepository(int idRepository) {
		List<Resource> resources = new ArrayList<Resource>();
		resources = resourceDao.getResourceListFromRepository(idRepository);
		List<ResourceDTO> resourcesDTO = new ArrayList<ResourceDTO>();
		for (Resource resource : resources) {
			resourcesDTO.add(conv.resourceToDTO(resource));
		}
		return resourcesDTO;
	}

	/**
	 * @author Zsombor
	 * @return String
	 * @param ResourceDTO
	 * returns content of a resource by id
	 */
	public String getResourceContent(ResourceDTO reDto){
		return resourceDao.getContent(reDto.getId());
	}
	
	/**
	 * @author Zsombor+zahariem
	 * @param ResourceDTO
	 * @param String
	 * modifies content of resource
	 */
	
	@Override
	public void modifyResourceContent(ResourceDTO reDto,int authorId){
		resourceDao.modifyContent(reDto.getId(),reDto.getContent());
	
		Date  date = new Date();
		String contentH = "Resource modified by "+authorId+" "+userDao.getUserById(authorId).getName();
		historyDao.addChangeToHistory(authorId, reDto.getId(), Type.modify_resource, contentH, date);
		String content = "Resource modified by "+authorId+" "+userDao.getUserById(authorId).getName();
		serverLogDao.insertOpToLog(LogType.modify_resource, content, date, userDao.getUserById(authorId));
		
		resourceDao.unlockResource(reDto.getId());
		
		content = "Resource unlocked by "+authorId+" "+userDao.getUserById(authorId).getName();
		serverLogDao.insertOpToLog(LogType.unlock_resource, content, date, userDao.getUserById(authorId));
	}
	
	/**
	 * @author tokea
	 * @param parentId
	 * @param name
	 * @return
	 */
	public boolean verifyUniqueness(int parentId,String name){
		boolean unique = resourceDao.verifyNameUniqueInFolder(parentId, name);
		return unique;
	}
	
	/**
	 * @author fodorl
	 * @param int
	 * @return List<ResourceDTO>
	 * returneaza resursele blocate din repository-ul cu id-ul dat
	 */
	
	public List<ResourceDTO> getLockedResources(int idRepository) {
		List<Resource> resources = new ArrayList<Resource>();
		List<Resource> lockedResources = new ArrayList<Resource>();
		resources = resourceDao.getResourceListFromRepository(idRepository);
		for (Resource resource: resources){
			if(resource.getLockUser().getId()!=1){
				lockedResources.add(resource);
			}
		}
		List<ResourceDTO> resourcesDTO = new ArrayList<ResourceDTO>();
		for (Resource resource : lockedResources) {
			resourcesDTO.add(conv.resourceToDTO(resource));
		}
		return resourcesDTO;
	}
	
	/**
	 * @author tokea
	 * @param idResource
	 * @return boolean locked
	 */
	@Override
	public boolean verifyLock(int idResource, int idUser){
		boolean locked = false;
		locked = resourceDao.verifyResourceLocked(idResource,idUser);
		return locked;
	}
	
	/**
	 * @author tokea
	 * @param idResource
	 * @return boolean locked
	 */
	@Override
	public boolean verifyLockedByUser(int idResource, int idUser){ 
		boolean locked = false;
		locked = resourceDao.verifyResourceLockedByUser(idResource,idUser);
		return locked;
	}
	
	/**
	 * @author tokea
	 * @param idRes
	 * @param idUser
	 * @return boolean lockSuccesful
	 */
	public boolean lockResource(int idRes,int idUser){
		boolean lockSuccesful = false;
		lockSuccesful = resourceDao.lockResource(idRes, idUser);
		
		Date  date = new Date();
		String content = "Resource locked by "+idUser;
		serverLogDao.insertOpToLog(LogType.modify_resource, content, date, userDao.getUserById(idUser));
		return lockSuccesful;
	}
	
	/**
	 * @author fodorl
	 * @return String
	 * returneaza numele resursei cu id-ul dat
	 */

	@Override
	public String getResourceNameById(int idResource) {
		
		return resourceDao.getNameById(idResource);
	}
}
